home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-12-12 | 5.8 KB | 327 lines | [TEXT/KAHL] |
- /***
- *
- * Functions.cp - built-in classes and functions
- *
- * Original code: Copyright (c) 1991, by David Michael Betz. All rights reserved
- * Modifications and additions: Copyright © by Christopher E. Hyde, 1995
- *
- ***/
-
- #include "Bob.h"
-
- // argument check macros
- #define ArgCount(cnt) { if (argc != cnt) WrongCount(argc, cnt); }
- #define CheckType(o,t) { if IsNotType(o, t) BadType(o,t); }
- #define Check0(t) { if IsNotType(0, t) Arg0Not(t); }
- #define CheckInt0() { if IsNotType(0, tInteger) Arg0NotInt(); }
- #define CheckInt1() { if IsNotType(1, tInteger) Arg1NotInt(); }
-
- #define DefOpFn(n) static _DefOpFn(x##n)
- #define AddOpFn(n) DefOpFn(n); AddFunction(#n, x##n)
-
- // external variables
- extern TValue symbols;
-
- // forward declarations
- static void AddFunction (KStr name, OpFn fcn);
- static void WrongCount (int n, int cnt);
- #pragma noreturn(WrongCount)
-
-
- // Initialize the internal functions
- void
- InitFunctions (void)
- {
- AddOpFn(typeof);
- AddOpFn(gc);
- AddOpFn(newvector);
- AddOpFn(newstring);
- AddOpFn(sizeof);
- AddOpFn(fopen);
- AddOpFn(fclose);
- AddOpFn(getc);
- AddOpFn(putc);
- AddOpFn(print);
- AddOpFn(getarg);
- AddOpFn(system);
-
- AddOpFn(getfile);
- // AddOpFn(putfile);
- AddOpFn(trace);
- }
-
-
- // Add a built-in function
- void
- AddFunction (KStr name, OpFn fcn)
- {
- Entry sym = AddEntry(&symbols, name, stSFunction);
-
- set_code(&sym->fValue, fcn);
- }
-
-
- // Set program tracing on/off
- DefOpFn(trace)
- {
- ArgCount(1);
- CheckInt0();
- Opt(TraceExec) = (sp->fInt != 0);
- ++sp;
- set_nil(sp);
- }
-
-
- #include <StandardFile.h>
-
-
- // Get an input file stream from the user
- DefOpFn(getfile)
- {
- SFTypeList typeList;
- StandardFileReply reply;
- short numTypes = -1;
-
- if (argc == 1) { // Optional argument is file type
- Check0(tString);
- if (SLen(sp) >= sizeof(OSType)) {
- typeList[0] = *(OSType*) SData(sp);
- numTypes = 1;
- }
- ++sp;
- } else
- ArgCount(0);
-
- StandardGetFile(nil, numTypes, typeList, &reply);
- if (reply.sfGood) {
- bool canDispose;
- Handle h = BBEdit->GetFileText(reply.sfFile.vRefNum,
- reply.sfFile.parID, reply.sfFile.name, &canDispose);
- FailNil(h);
- gInput.Close();
- gInput.Open(h, canDispose);
- // set_iostream(sp, newiostream(&fileio, fp));
- }
- set_integer(sp, reply.sfGood);
- }
-
-
- // Get the data type of a value
- DefOpFn(typeof)
- {
- ArgCount(1);
- set_integer(&sp[1], sp->fType);
- ++sp;
- }
-
-
- // Invoke the garbage collector
- DefOpFn(gc)
- {
- ArgCount(0);
- GC();
- set_nil(sp);
- }
-
-
- // Allocate a new vector
- DefOpFn(newvector)
- {
- ArgCount(1);
- CheckInt0();
- int size = sp->fInt;
- set_vector(&sp[1], NewVector(size));
- ++sp;
- }
-
-
- // Allocate a new string
- DefOpFn(newstring)
- {
- ArgCount(1);
- CheckInt0();
- int size = sp->fInt;
- set_string(&sp[1], NewString(size));
- ++sp;
- }
-
-
- // Get the size of a vector or string
- DefOpFn(sizeof)
- {
- ArgCount(1);
- if (sp->fType == tVector || sp->fType == tString)
- set_integer(&sp[1], VLen(sp));
- ++sp;
- }
-
-
- // Open a file
- DefOpFn(fopen)
- {
- char name[50], mode[10];
- FILE* fp;
-
- ArgCount(2);
- Check0(tString);
- CheckType(1, tString);
- GetCString(name, sizeof(name), &sp[1]);
- GetCString(mode, sizeof(mode), &sp[0]);
- #if 0
- if ((fp = fopen(name, mode)) == nil)
- set_nil(&sp[2]);
- else
- set_iostream(&sp[2], newiostream(&fileio, fp));
- #else
- set_nil(&sp[2]);
- #endif
- sp += 2;
- }
-
-
- // Close a file
- DefOpFn(fclose)
- {
- ArgCount(1);
- Check0(tStream);
- // set_integer(&sp[1], iosclose(&sp[0]));
- iosclose(&sp[0]);
- set_integer(&sp[1], 0);
- ++sp;
- }
-
-
- // Get a character from a file
- DefOpFn(getc)
- {
- ArgCount(1);
- Check0(tStream);
- set_integer(&sp[1], iosgetc(&sp[0]));
- ++sp;
- }
-
-
- // Output a character to a file
- DefOpFn(putc)
- {
- ArgCount(2);
- Check0(tStream);
- CheckInt1();
- // set_integer(&sp[2], iosputc((int)sp[1].fInt, &sp[0]));
- iosputc(char(sp[1].fInt), &sp[0]);
- set_integer(&sp[2], 0);
- sp += 2;
- }
-
-
- // Generic print function
- DefOpFn(print)
- {
- extern TValue stdout_iostream;
-
- for (int n = argc; --n >= 0; )
- Print(&stdout_iostream, false, &sp[n]);
- sp += argc;
- set_nil(sp);
- }
-
-
- // Print one value
- void
- Print (Value ios, bool quoteIt, ConstValue val)
- {
- char buf[200];
- TId name;
-
- switch (val->fType) {
- case tNil:
- iosputs("nil", ios);
- break;
- case tClass:
- GetCString(name, sizeof(name), clgetname(val));
- sprintf(buf, "#<Class-%s>", name);
- iosputs(buf, ios);
- break;
- case tObject:
- sprintf(buf, "#<Object-%lX>", objaddr(val));
- iosputs(buf, ios);
- break;
- case tVector:
- sprintf(buf, "#<Vector-%lX>", vecaddr(val));
- iosputs(buf, ios);
- break;
- case tInteger:
- sprintf(buf, "%ld", val->fInt);
- iosputs(buf, ios);
- break;
- case tString:
- if (quoteIt) iosputc('"', ios);
- ((COStream*) ios_t(ios))->Put(SData(val), SLen(val));
- if (quoteIt) iosputc('"', ios);
- break;
- case tByteCode:
- sprintf(buf, "#<Bytecode-%lX>", vecaddr(val));
- iosputs(buf, ios);
- break;
- case tCode:
- sprintf(buf, "#<Code-%lX>", val->fCode);
- iosputs(buf, ios);
- break;
- case tVar:
- Value aClass = digetclass(degetdictionary(val));
- if (!isnil(aClass)) {
- GetCString(name, sizeof(name), clgetname(aClass));
- sprintf(buf, "%s::", name);
- iosputs(buf, ios);
- }
- GetCString(name, sizeof(name), degetkey(val));
- iosputs(name, ios);
- break;
- case tStream:
- sprintf(buf, "#<Stream-%lX>", val->fStream);
- iosputs(buf, ios);
- break;
- default:
- Error("Undefined type: %d", valtype(val));
- }
- }
-
-
- // Get an argument from the argument list
- DefOpFn(getarg)
- {
- extern char** bobargv;
- extern int bobargc;
-
- ArgCount(1);
- CheckInt0();
- int i = sp[0].fInt;
- if (i >= 0 && i < bobargc)
- set_string(&sp[1], MakeString(bobargv[i]));
- else
- set_nil(&sp[1]);
- ++sp;
- }
-
-
- // xsystem - execute a system command
- DefOpFn(system)
- {
- char cmd[133];
-
- ArgCount(1);
- Check0(tString);
- GetCString(cmd, sizeof(cmd), &sp[0]);
- // set_integer(&sp[1], system(cmd));
- set_integer(&sp[1], -1);
- ++sp;
- }
-
-
- // Report wrong number of arguments
- void
- WrongCount (int n, int cnt)
- {
- Error((n < cnt) ? "Too many arguments" : "Too few arguments");
- }
-